package galatea;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class IDE extends JFrame implements ListSelectionListener, ActionListener, DocumentListener{
	JMenuBar menuBar;
	JMenu file;
	JMenu newStuff;
		JMenuItem newRobot, newFile;
	JMenuItem open;
	JMenuItem save, saveAs;
	JMenuItem imp, exp;
	JMenuItem recent[];
	JMenuItem exit;
	
	JMenu edit;
	JMenuItem undo, redo;
	JMenuItem copy, paste;
	
	JMenu robot;
	JMenuItem compile, load;
	JMenu selChip;
	ButtonGroup chipGroup;
		JRadioButtonMenuItem galatea, arduino, atmega8, atmega328, atmega2560;
	JMenu selProg;
	ButtonGroup progGroup;
		JRadioButtonMenuItem galateaISP, arduinoISP, usbTiny;
	
	JMenu project;
	JMenuItem addModule;
	
	JMenu myCloud;
	JMenuItem importFunc;
	
	JMenu theCloud;
	JMenuItem importCloud;
		
	JToolBar toolbar;
		
	JSplitPane masterSplit;
	JSplitPane leftSplit;
	
	JScrollPane rightScroll;
	JScrollPane objScroll;
	JScrollPane layerScroll;
	
	LayerList layers;
	
	ObjectList objList;
	DefaultListModel functions;
	DefaultListModel objects;
	DefaultListModel components;
	DefaultListModel systems;
	DefaultListModel robots;
	
	DefaultListModel lists[];
	String listNames[];
	Color listColors[];
	String listTexts[];
	GraphicWindow listPanels[];
	
	int currLayer;
	
	JTabbedPane mainTabs;
	TextWindow textWindow;
	
	IDE(){
		super("Galatea IDE");
	    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	    
	    menuBar = new JMenuBar();
	    file = new JMenu("File");
	    newStuff = new JMenu("New");
	    	newRobot = new JMenuItem("Robot");
	    	newFile = new JMenuItem("File");
	    open = new JMenuItem("Open");
	    save = new JMenuItem("Save");
	    saveAs = new JMenuItem("Save As");
	    imp = new JMenuItem("Import");
	    exp = new JMenuItem("Export");
	    recent = new JMenuItem[5];
	    	/*recent[0].setText("Recent File 1");
	    	recent[1].setText("Recent File 2");
	    	recent[2].setText("Recent File 3");
	    	recent[3].setText("Recent File 4");
	    	recent[4].setText("Recent File 5");*/
	    exit = new JMenuItem("Exit");
	    
	    edit = new JMenu("Edit");
	    undo = new JMenuItem("Undo");
	    redo = new JMenuItem("Redo");
	    copy = new JMenuItem("Copy");
	    paste = new JMenuItem("Paste");
	    
	    robot = new JMenu("Robot");
	    compile = new JMenuItem("Compile");
	    load = new JMenuItem("Load");
	    selChip = new JMenu("Select Chip");
	    chipGroup = new ButtonGroup();
	    	galatea = new JRadioButtonMenuItem("Galatea");
	    	arduino = new JRadioButtonMenuItem("Arduino");
	    	atmega8 = new JRadioButtonMenuItem("ATmega8");
	    	atmega328 = new JRadioButtonMenuItem("ATmega328");
	    	atmega2560 = new JRadioButtonMenuItem("ATmega2560");
	    selProg = new JMenu("Select Programmer");
	    progGroup = new ButtonGroup();
	    	galateaISP = new JRadioButtonMenuItem("Galatea ISP");
	    	arduinoISP = new JRadioButtonMenuItem("ArduinoISP");
	    	usbTiny = new JRadioButtonMenuItem("usbTiny");
	    	
	    project = new JMenu("Project");
	    addModule = new JMenuItem("Add Module");
	    
	    myCloud = new JMenu("My Cloud");
	    importFunc = new JMenuItem("Import");
	    
	    theCloud = new JMenu("The Cloud");
	    importCloud = new JMenuItem("Import");
	    
	    menuBar.add(file);
	    file.add(newStuff);
	    	newStuff.add(newRobot);
	    	newStuff.add(newFile);
	    file.add(open);
	    file.addSeparator();
	    file.add(save);
	    file.add(saveAs);
	    file.addSeparator();
	    file.add(imp);
	    file.add(exp);
	    file.addSeparator();
	    file.addSeparator();
	    file.add(exit);
	    
	    menuBar.add(edit);
	    edit.add(undo);
	    edit.add(redo);
	    edit.addSeparator();
	    edit.add(copy);
	    edit.add(paste);
	    
	    menuBar.add(robot);
	    robot.add(compile);
	    robot.add(load);
	    robot.addSeparator();
	    robot.add(selChip);
	    	selChip.add(galatea);
	    	chipGroup.add(galatea);
	    	selChip.add(arduino);
	    	chipGroup.add(arduino);
	    	selChip.add(atmega8);
	    	chipGroup.add(atmega8);
	    	selChip.add(atmega328);
	    	chipGroup.add(atmega328);
	    	selChip.add(atmega2560);
	    	chipGroup.add(atmega2560);
	    robot.add(selProg);
	    	selProg.add(galateaISP);
	    	progGroup.add(galateaISP);
	    	selProg.add(arduinoISP);
	    	progGroup.add(arduinoISP);
	    	selProg.add(usbTiny);
	    	progGroup.add(usbTiny);
	    	
	    menuBar.add(project);
	    project.add(addModule);
	    addModule.addActionListener(this);
	    
	    menuBar.add(myCloud);
	    myCloud.add(importFunc);
	    
	    menuBar.add(theCloud);
	    theCloud.add(importCloud);
	    
	    this.setJMenuBar(menuBar);
	    
	    toolbar = new JToolBar();
	    toolbar.add(new JButton("New"));
	    toolbar.add(new JButton("Save"));
	    toolbar.add(new JButton("Compile"));
	    toolbar.add(new JButton("Load"));
	    
	    this.add(toolbar, BorderLayout.PAGE_START);
	    
	    currLayer = 0;
	    layers = new LayerList();
	    layers.setSelectedIndex(5-currLayer);
	    layers.addListSelectionListener(this);
	    
	    layerScroll = new JScrollPane(layers);
	    
	    /*
	    functions = new ObjectList("Function List");
	    objects = new ObjectList("Object List");
	    modules = new ObjectList("Module List");
	    systems = new ObjectList("System List");
	    robots = new ObjectList("Robot List");
	    
	    layObjLists = new ObjectList[6];
	    layObjLists[0] = functions;
	    layObjLists[1] = objects;
	    layObjLists[2] = modules;
	    layObjLists[3] = systems;
	    layObjLists[4] = robots;
	    layObjLists[5] = new ObjectList("");
	    
	    
	    for (ObjectList olist: layObjLists){
	    	olist.setDragEnabled(true);
	    }
	    */
	    
	    functions = new DefaultListModel();
	    objects = new DefaultListModel();
	    components = new DefaultListModel();
	    systems = new DefaultListModel();
	    robots = new DefaultListModel();
	    
	    lists = new DefaultListModel[6];
	    lists[0] = functions;
	    lists[1] = objects;
	    lists[2] = components;
	    lists[3] = systems;
	    lists[4] = robots;
	    lists[5] = new DefaultListModel();
	    
	    listNames = new String[6];
	    listNames[0] = "Function List";
	    listNames[1] = "Object List";
	    listNames[2] = "Component List";
	    listNames[3] = "System List";
	    listNames[4] = "Robot List";
	    listNames[5] = "";
	    
	    listColors = new Color[6];
	    listColors[0] = Color.GREEN;
	    listColors[1] = Color.CYAN;
	    listColors[2] = Color.MAGENTA;
	    listColors[3] = Color.RED;
	    listColors[4] = Color.ORANGE;
	    listColors[5] = Color.GRAY;
	    
	    listTexts = new String[6];
	    
	    listPanels = new GraphicWindow[6];
	    for (int i = 0; i < 6; i++){
	    	listPanels[currLayer] = new GraphicWindow();
	    	listTexts[currLayer] = new String();
	    }
	    
	    objList = new ObjectList(lists[currLayer], listNames[currLayer]);
	    
	    objScroll = new JScrollPane(objList);
	    
	    objList.setDragEnabled(true);
	    
	    leftSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT, objScroll, layers);
	    leftSplit.setDividerLocation(750);
	    
	    textWindow = new TextWindow();
	    textWindow.setText(listTexts[currLayer]);
	    textWindow.doc.addDocumentListener(this);
	    
	    mainTabs = new JTabbedPane();
	    mainTabs.addTab("Text View", textWindow);
	    mainTabs.addTab("Module View", listPanels[currLayer]);
	    
	    rightScroll = new JScrollPane(mainTabs);
	    
	    masterSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftSplit, rightScroll);
	    masterSplit.setDividerLocation(250);
	    
	    this.add(masterSplit);
	    
	    setSize(1000, 1000);
	    setVisible(true);
	    this.setExtendedState(JFrame.MAXIMIZED_BOTH);
	    
	}
	
	
	
	public static void main(String args[]){
		IDE ide = new IDE();
	}

	@Override
	public void valueChanged(ListSelectionEvent e) {
		if (e.getValueIsAdjusting() == false){
			if (layers.getSelectedIndex() != -1){
				layerUpdate(layers.getSelectedIndex());
				this.repaint();
			}
		}
	}



	private void layerUpdate(int newLayer) {
		listTexts[currLayer] = textWindow.getText();
		currLayer = 5-newLayer;
		objList.changeList(lists[currLayer], listNames[currLayer]);
		textWindow.setText(listTexts[currLayer]);
	}

	public void actionPerformed(ActionEvent e) {
		String newModText = textWindow.getSelectedText();
		String inputs[] = newModText.split("\n", 5);
		if (currLayer <= 5 && inputs.length >= 5 && inputs[0].startsWith("//NAME:") && inputs[1].startsWith("//INPUT:") && inputs[2].startsWith("//OUTPUT:") && inputs[3].startsWith("//DESC:")){
			/*for (String s:inputs){
				System.out.println(s);
			}*/
			inputs[0] = inputs[0].replaceFirst("//NAME:", "");
			inputs[1] = inputs[1].replaceFirst("//INPUT:", "");
			inputs[2] = inputs[2].replaceFirst("//OUTPUT:", "");
			inputs[3] = inputs[3].replaceFirst("//DESC:", "");
			
			inputs[0] = inputs[0].trim();
			inputs[1] = inputs[1].trim();
			inputs[2] = inputs[2].trim();
			inputs[3] = inputs[3].trim();
			
			/*for (String s:inputs){
				System.out.println(s);
			}
			*/
			String code = null;
			for (int i = 4; i < inputs.length; i++)
				code += inputs[i];
			
			ListObject newMod = new ListObject(inputs[0], listColors[currLayer+1], inputs[1], inputs[2], inputs[3], code);
			newMod.addMouseMotionListener(listPanels[currLayer]);
			listPanels[currLayer].addMod(newMod, listColors[currLayer+1]);
			
			lists[currLayer].addElement(newMod);
			layerUpdate(5-currLayer);
		}
		else if (currLayer > 5){
			JOptionPane.showMessageDialog(this,		"No more layers!!!", "Out of Layers", JOptionPane.ERROR_MESSAGE);
		}
		else{
			JOptionPane.showMessageDialog(this, 	"Please use the format:\n" +
													"//NAME:\n" +
													"//INPUT:\n" +
													"//OUTPUT:\n" +
													"//DESC:" +
													"<function>",
													"Format Error",
													JOptionPane.ERROR_MESSAGE);
		}
	}
	@Override
	public void changedUpdate(DocumentEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void insertUpdate(DocumentEvent arg0) {
		SwingUtilities.invokeLater(textWindow.doWorkRunnable);
	}

	@Override
	public void removeUpdate(DocumentEvent arg0) {
		SwingUtilities.invokeLater(textWindow.doWorkRunnable);
	}
}
